'use strict';

const moment = require('moment');

// +----------------------------------------------------------------------
// | CmsWing [ 网站内容管理框架 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2015-2115 http://www.cmswing.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: arterli <arterli@qq.com>
// +----------------------------------------------------------------------
// const Jimp = require('jimp');
module.exports = class extends think.cmswing.center {
    async __before() {
        await super.__before();
        // 判断是否登陆
        // await this.weblogin();
        if (!this.is_login) {
            // 判断浏览客户端
            if (this.isMobile) {
                // 手机端直接跳转到登录页面
                return this.redirect('/center/public/login');
            }
            return this.redirect('/cmswing/error/login');

        }
    }
    /**
     * 账户金额管理
     * @return {PreventPromise} ?
     */
    async indexAction() {
        this.tactive = 'user';
        const type = parseInt(this.get('type')) || null;
        let data;
        if (think.isEmpty(type)) {
            data = await this.model('balance_log').where({ user_id: this.user.uid }).page(this.get('page'))
                .order('time DESC')
                .countSelect();
        } else if (type === 1) {
            data = await this.model('balance_log').where({ user_id: 10000 }).page(this.get('page'))
                .order('time DESC')
                .countSelect();
        } else {
            data = await this.model('order').where({
                user_id: this.user.uid,
                type: 1,
                is_del: 0,
            }).page(this.get('page'))
                .order('create_time DESC')
                .countSelect();
            for (const val of data.data) {
                val.channel = await this.model('pingxx').where({ id: val.payment }).getField('title', true);
            }
        }

        const html = this.pagination(data);
        // think.log(data);
        this.assign('pagination', html);
        this.assign('list', data.data);
        this.assign('type', type);
        this.assign('count', data.count);
        // 获取用户信息
        const userInfo = await this.model('member').find(this.user.uid);
        this.assign('userInfo', userInfo);
        // 未付款的充值订单统计
        const unpaid = await this.model('order').where({
            user_id: this.user.uid,
            type: 1,
            is_del: 0,
            pay_status: 0,
        }).count('id');
        this.assign('unpaid', unpaid);
        this.meta_title = '账户金额管理';
        // 判断浏览客户端
        if (this.isMobile) {
            if (this.isAjax('get')) {
                for (const v of data.data) {
                    v.time = this.moment(v.create_time).format('YYYY-MM-DD HH:mm:ss');
                    v.amount = formatCurrency(v.amount);
                    v.amount_log = formatCurrency(v.amount_log);
                }
                return this.json(data);
            }
            this.active = 'user/index';
            return this.display(this.mtpl());

        }
        return this.display();

    }

    /**
     * 充值
     */
    async rechargeAction() {
        if (this.isAjax('POST')) {
            const data = this.post();
            if (think.isEmpty(data.order_amount)) {
                return this.fail('请输入金额！');
            } else if (!think.isNumberString(data.order_amount)) {
                return this.fail('金额类型错误！');
            } else if (think.isEmpty(data.payment)) {
                return this.fail('必须选一种支付方式！');
            }

            // 用户
            data.user_id = this.user.uid;
            // 生成订单编号//todo
            // let nowtime = new Date().valueOf();
            // let oid = ["c", this.user.uid, nowtime]);
            data.order_no = await this.model('cmswing/order').orderid(this.user.uid);
            // 支付状态 pay_stayus 0:未付款 ,1:已付款
            data.pay_status = 0;
            // 订单状态 status 2:等待审核，3:已审核
            data.status = 2;
            // 发货状态 type 0:普通，1:充值
            data.type = 1;
            // 订单创建时间 create_time
            data.create_time = new Date().valueOf();
            // 生成订单

            // 判断是否已经绑定pingxx_id,如果已绑定查询pingxx订单直接支付。防止订单重复生成。
            // console.log(111111111)
            // 获取渠道
            const channel = await this.model('pingxx').where({ id: data.payment }).getField('channel', true);

            let open_id;
            if (channel === 'wx_pub') {
                open_id = await this.session('wx_openid');
            }
            // 调用ping++ 服务端
            const payment = this.service('cmswing/payment', this.ctx);
            // 传入 channel,order_no,order_amount,this.ip()
            const ip = think.env === 'development' ? '127.0.0.1' : this.ip;
            const charges = await payment.pingxx(channel, data.order_no, data.order_amount, ip, open_id);
            // console.log(charges);
            if (charges) {
                // 把pingxx_id存到订单
                data.pingxx_id = charges.id;
                const order_id = await this.model('order').add(data);

                // 支付日志
                const receiving = {
                    order_id,
                    user_id: this.user.uid,
                    amount: data.order_amount,
                    create_time: new Date().getTime(),
                    payment_time: new Date().getTime(),
                    doc_type: 1,
                    payment_id: data.payment,
                    pay_status: 0,
                };
                await this.model('doc_receiving').add(receiving);
                return this.success({ name: '支付订单对接成功，正在转跳！', data: charges });
            }
            return this.fail('调用接口失败！');
            // think.log(data);
        }
        // ping++ 支付渠道 pc网页
        // 根据不同的客户端调用不同的支付方式
        let map;
        if (this.isMobile) {
            map = {
                type: 2,
                status: 1,
            };
            if (!this.isweixin) {
                map.channel = [ '!=', 'wx_pub' ];
            }
        } else {
            map = {
                type: 1,
                status: 1,
            };
        }
        const paylist = await this.model('pingxx').where(map).order('sort ASC')
            .select();
        this.assign('paylist', paylist);
        this.meta_title = '充值';
        if (this.isMobile) {
            this.active = 'user/index';
            return this.display(this.mtpl());
        }

        return this.display();
    }

    /**
     * 购买会员
     */
    async membershipAction() {
        const { ctx } = this;
        if (ctx.isAjax()) {
            const params = ctx.param();
            const groupId = params.groupId; // 组ID
            const type = params.type; // 购买类型 天(d)day、月(m)month、年(y)year、长期(l)long
            const time = params.time; // 购买时长 类型值是长期值为0 值为天｜月｜年值为1-100
            const step = params.step;
            const price = params.price;
            const memberInfo = await this.model('member').where({ id: this.user.uid }).find(); // 读取用户信息
            let currentGroupInfo, // 当前用户组
                targetGroupInfo; // 目标用户组
            const groupsInfo = await this.model('member_group').where({
                groupid: [ 'in', `${memberInfo.groupid}, ${groupId}` ],
            }).select(); // 读取用户组信息
            // 当用户组不存在
            if (groupsInfo.length < 2) {
                return this.fail('你选择的用户组不存在，请选择其它用户组');
            }
            // 提取当前或目标用户组
            if (groupsInfo[0].groupid === memberInfo.groupid) {
                currentGroupInfo = groupsInfo[0];
                targetGroupInfo = groupsInfo[1];
            } else {
                currentGroupInfo = groupsInfo[1];
                targetGroupInfo = groupsInfo[0];
            }
            // 判断用户当前用户是否已经购买会员
            if (memberInfo.recharge_type !== '' && moment(memberInfo.overduedate).isAfter(moment())) {
                return this.fail(`你已经是${currentGroupInfo.name}会员，如果你需要提升会员级别请选择升级会员`);
            }
            // 计算价格
            const upgradePrice = type !== 'l' ? targetGroupInfo[`price_${type}`] * time : targetGroupInfo[`price_${type}`];
            // 步骤 1-计算价格 2-购买会员
            if (step === 1) {
                return this.success(upgradePrice);
            }
            // 验证提交的价格和计算的价格
            if (Number(price) !== upgradePrice) {
                return this.fail('系统检测到你恶意修改价格，已经记录你的相关行为');
            }
            // 用户余额够则使用余额支付
            const balance = memberInfo.amount; // 余额
            if (balance < upgradePrice) {
                return this.fail('你的余额不足，请先充值');
            }
            // 扣款
            try {
                // 修改用户组和到期日
                await this.model('member').where({ id: this.user.uid }).update({
                    amount: memberInfo.amount - price,
                    recharge_type: type,
                    overduedate: moment().add(time, type === 'm' ? 'M' : type).format('x'),
                    groupid: groupId,
                });
                return this.success('恭喜你已经成为尊贵的 ' + targetGroupInfo.name + ' 会员');
            } catch (e) {
                think.logger.error(e);
                return this.file('失败，发生错误');
            }
        }
        // 读取用户组
        const groupsInfo = await this.model('member_group').order('sort ASC').select();
        // 提取权限
        const privInfo = await this.model('category_priv').where({ catid: 1 }).select();
        const privGroup = {}; // 分组
        const privGroupAuth = {}; // 存储使用了限制权限的分组 如果分组不在这个对象里表示这个分组不限制权限
        // 遍历分类权限
        for (const v of privInfo) {
            if (v.is_admin === 0) {
                privGroup[v.roleid] = [];
                privGroupAuth[v.action] = 1; // 表示这个分组使用了权限
            }
        }
        // 用户组权限
        for (const v in privGroup) {
            const arr = [];
            for (const m of privInfo) {
                if (parseInt(v) === m.roleid && m.is_admin === 0) {
                    arr.push(m.action);
                }
            }
            privGroup[v] = arr;
        }
        this.assign('privGroupAuth', privGroupAuth);
        this.meta_title = '购买会员';
        if (this.isMobile) {
            this.assign('memberGroupPicker', groupsInfo.map(item => {
                return {
                    text: item.name,
                    value: item.groupid,
                    l: item.price_l,
                    y: item.price_y,
                    m: item.price_m,
                };
            })); // 会员组选项
            return this.display(this.mtpl());
        }
        this.assign('privGroup', privGroup);
        this.assign('groupsInfo', groupsInfo);
        return this.display();
    }

    /**
     * 会员续费
     */
    async renewAction() {
        const { ctx } = this;
        const memberInfo = await this.model('member').where({ id: this.user.uid }).find(); // 读取用户信息
        if (ctx.isAjax()) {
            const params = ctx.param();
            const type = params.type; // 购买类型 天(d)day、月(m)month、年(y)year、长期(l)long
            const time = params.time; // 购买时长 类型值是长期值为0 值为天｜月｜年值为1-100
            const step = params.step;
            const price = params.price;
            const groupInfo = await this.model('member_group').where({
                groupid: memberInfo.groupid,
            }).find(); // 读取用户组信息
            // 当用户组不存在
            if (groupInfo.length === 0) {
                return this.fail('你选择的用户组不存在，请选择其它用户组');
            }
            if (memberInfo.recharge_type === 'l') {
                return this.fail('你的账号拥有永久会员时长，如果你想升级会员，请选择升级用户组');
            }
            if (memberInfo.recharge_type === '') {
                return this.fail('你还没有购买会员，请先购买会员');
            }
            // 计算价格
            const upgradePrice = type !== 'l' ? groupInfo[`price_${memberInfo.recharge_type}`] * time : groupInfo[`price_${memberInfo.recharge_type}`];
            // 步骤 1-计算价格 2-购买会员
            if (step === 1) {
                return this.success(upgradePrice);
            }
            // 验证提交的价格和计算的价格
            if (Number(price) !== upgradePrice) {
                return this.fail('系统检测到你恶意修改价格，已经记录你的相关行为');
            }
            // 用户余额够则使用余额支付
            const balance = memberInfo.amount; // 余额
            if (balance < upgradePrice) {
                return this.fail('你的余额不足，请先充值');
            }
            // 扣款
            try {
                // 修改用户组和到期日
                await this.model('member').where({ id: this.user.uid }).update({
                    amount: memberInfo.amount - price,
                    recharge_type: type,
                    overduedate: moment(memberInfo.overduedate).add(time, type === 'm' ? 'M' : type).format('x'),
                    groupid: memberInfo.groupid,
                });
                return this.success('恭喜你已经成功续费会员');
            } catch (e) {
                think.logger.error(e);
                return this.file('失败，发生错误');
            }
        }
        // 读取用户组
        const groupInfo = await this.model('member_group').where({ groupid: memberInfo.groupid }).find();
        this.meta_title = '会员续费';
        this.assign('moment', moment);
        this.assign('memberInfo', memberInfo);
        this.assign('groupInfo', groupInfo);
        if (this.isMobile) {
            this.assign('timeTypePicker', [
                {
                    text: groupInfo.price_m + '元/月',
                    value: 'm',
                },
                {
                    text: groupInfo.price_y + '元/年',
                    value: 'y',
                },
                {
                    text: groupInfo.price_l + '元/长期',
                    value: 'l',
                },
            ]);
            return this.display(this.mtpl());
        }
        return this.display();
    }

    /**
     * 升级用户组
     */
    async upgradeAction() {
        const { ctx } = this;
        if (ctx.isAjax()) {
            const params = ctx.param();
            const groupId = params.groupId; // 组ID
            const step = params.step;
            const price = params.price;
            const memberInfo = await this.model('member').where({ id: this.user.uid }).find(); // 读取用户信息
            let currentGroupInfo, // 当前用户组
                targetGroupInfo; // 目标用户组
            if (memberInfo.groupid === groupId) {
                return this.fail('你选择会员和你当前的会员级别一样，请选择其它会员');
            }
            const groupsInfo = await this.model('member_group').where({
                groupid: [ 'in', `${memberInfo.groupid}, ${groupId}` ],
            }).select(); // 读取用户组信息
            // 当用户组不存在
            if (groupsInfo.length < 2) {
                return this.fail('你选择的用户组不存在，请选择其它用户组');
            }
            // 提取当前或目标用户组
            if (groupsInfo[0].groupid === memberInfo.groupid) {
                currentGroupInfo = groupsInfo[0];
                targetGroupInfo = groupsInfo[1];
            } else {
                currentGroupInfo = groupsInfo[1];
                targetGroupInfo = groupsInfo[0];
            }
            // 判断用户当前用户是否已经购买会员
            if (memberInfo.recharge_type === '' || (memberInfo.recharge_type !== '' && memberInfo.recharge_type !== 'l' && moment(memberInfo.overduedate).isBefore(moment()))) {
                return this.fail('你还不是VIP会员或会员已经到期');
            }
            // 计算当前用户组价值
            let membershipValue, // 用户价值
                newMembershipValue; // 新会员所需价值
            const currentType = memberInfo.recharge_type;

            const remainingDays = moment(memberInfo.overduedate).diff(moment(), 'days'); // 剩余天数
            switch (currentType) {
            case 'l': // 长期
                membershipValue = currentGroupInfo.price_l;
                break;
            case 'y': // 年
                membershipValue = Math.ceil(currentGroupInfo.price_y / 365 * remainingDays * 100) / 100;
                newMembershipValue = Math.ceil(targetGroupInfo.price_y / 365 * remainingDays * 100) / 100;
                break;
            case 'm': // 月
                membershipValue = Math.ceil(currentGroupInfo.price_m / 30 * remainingDays * 100) / 100;
                newMembershipValue = Math.ceil(targetGroupInfo.price_m / 30 * remainingDays * 100) / 100;
                break;
                // case 'd': // 天
                //     membershipValue = currentGroupInfo.price_d * remainingDays;
                //     newMembershipValue = targetGroupInfo.price_d * remainingDays;
                //     break;
            default: // 未购买
                membershipValue = 0;
                newMembershipValue = 0;
            }
            // 计算价格与用户选择的价格是否一致 或者 升级价格小于用户组价值
            if (newMembershipValue < membershipValue) {
                return this.fail('请选择比当前等级高的会员等级');
            }
            // 计算价格
            const upgradePrice = Math.floor((newMembershipValue - membershipValue) * 100) / 100;
            // 步骤 1-计算价格 2-购买会员
            if (step === 1) {
                return this.success({ old: membershipValue, new: newMembershipValue, upgrade: upgradePrice });
            }
            // 验证提交的价格和计算的价格
            if (Number(price) !== upgradePrice) {
                return this.fail('系统检测到你恶意修改价格，已经记录你的相关行为');
            }
            // 用户余额够则使用余额支付
            const balance = memberInfo.amount; // 余额
            if (balance < upgradePrice) {
                return this.fail('你的余额不足，请先充值');
            }
            // 扣款
            try {
                // 修改用户级别
                await this.model('member').where({ id: this.user.uid }).update({
                    amount: memberInfo.amount - price,
                    groupid: groupId,
                });
                return this.success('恭喜你已经成为尊贵的 ' + targetGroupInfo.name + ' 会员');
            } catch (e) {
                think.logger.error(e);
                return this.file('失败，发生错误');
            }
        }
        // 读取用户组
        const groupsInfo = await this.model('member_group').order('sort ASC').select();
        // 提取权限
        const privInfo = await this.model('category_priv').where({ catid: 1 }).select();
        const privGroup = {}; // 分组
        const privGroupAuth = {}; // 存储使用了限制权限的分组 如果分组不在这个对象里表示这个分组不限制权限
        // 遍历分类权限
        for (const v of privInfo) {
            if (v.is_admin === 0) {
                privGroup[v.roleid] = [];
                privGroupAuth[v.action] = 1; // 表示这个分组使用了权限
            }
        }
        // 用户组权限
        for (const v in privGroup) {
            const arr = [];
            for (const m of privInfo) {
                if (parseInt(v) === m.roleid && m.is_admin === 0) {
                    arr.push(m.action);
                }
            }
            privGroup[v] = arr;
        }
        this.assign('mod', {
            temp_show: 1,
            type_show: 1,
            priv_show: 1,
            groups_show: 1,
        });
        this.meta_title = '升级会员';
        if (this.isMobile) {
            this.assign('memberGroupPicker', groupsInfo.map(item => {
                return {
                    text: item.name,
                    value: item.groupid,
                };
            })); // 会员组选项
            return this.display(this.mtpl());
        }
        this.assign('privGroupAuth', privGroupAuth);
        this.assign('privGroup', privGroup);
        this.assign('groupsInfo', groupsInfo);
        return this.display();
    }
};
